package com.smartsystem.common.security;

import com.smartsystem.common.utils.JWTUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * JWT认证过滤器
 */
@Slf4j
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    
    private static final String AUTH_HEADER = "Authorization";
    private static final String TOKEN_PREFIX = "Bearer ";
    
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String requestURI = request.getRequestURI();
        
        // 白名单路径，直接跳过JWT验证
        if (isWhiteListPath(requestURI)) {
            filterChain.doFilter(request, response);
            return;
        }
        
        try {
            // 获取令牌
            String token = getJwtFromRequest(request);
            log.info("JWT过滤器 - 请求URI: {}, Token: {}", requestURI, token != null ? "存在" : "不存在");
            
            if (token != null) {
                // 解析令牌
                Claims claims = JWTUtils.parseToken(token);
                String username = claims.get("username", String.class);
                log.info("JWT过滤器 - 解析Token成功, 用户名: {}", username);
                
                if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                    // 创建认证对象
                    List<SimpleGrantedAuthority> authorities = new ArrayList<>();
                    // 实际应用中应该从数据库或缓存中获取用户的角色和权限
                    // 这里简化处理，只添加一个默认角色
                    authorities.add(new SimpleGrantedAuthority("ROLE_USER"));
                    
                    UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
                            username, null, authorities);
                    
                    // 设置认证信息
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    log.info("JWT过滤器 - 认证设置成功, 用户: {}", username);
                }
            } else {
                log.warn("JWT过滤器 - 未找到Token, URI: {}", requestURI);
            }
        } catch (Exception e) {
            log.error("JWT过滤器 - 无法设置用户认证信息: " + e.getMessage(), e);
        }
        
        // 继续过滤器链
        filterChain.doFilter(request, response);
    }
    
    /**
     * 检查是否为白名单路径
     * @param requestURI 请求URI
     * @return 是否为白名单路径
     */
    private boolean isWhiteListPath(String requestURI) {
        String[] whiteList = {
            "/", "/index.html", "/api",
            "/api/v1/auth/login", "/api/v1/auth/register", "/api/test",
            "/doc.html", "/webjars", "/v3/api-docs", "/swagger-ui", "/swagger-resources",
            "/druid", "/actuator", "/static", "/css", "/js", "/images", "/favicon.ico", "/error"
        };
        
        for (String path : whiteList) {
            if (requestURI.equals(path) || requestURI.startsWith(path + "/")) {
                return true;
            }
        }
        return false;
    }
    
    /**
     * 从请求头中获取JWT令牌
     * @param request 请求
     * @return JWT令牌
     */
    private String getJwtFromRequest(HttpServletRequest request) {
        String bearerToken = request.getHeader(AUTH_HEADER);
        if (bearerToken != null && bearerToken.startsWith(TOKEN_PREFIX)) {
            return bearerToken.substring(TOKEN_PREFIX.length());
        }
        return null;
    }
}